﻿using System;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using System.Text;

namespace NetPay.WeChat.ProfitSharing
{
    /// <summary>
    /// AES-GCM是一种NIST标准的认证加密算法， 是一种能够同时保证数据的保密性、 完整性和真实性的一种加密模式。它最广泛的应用是在TLS中。
    /// 证书和回调报文加解密
    /// </summary>
	public class AesGcmHelper
	{
        /// <summary>
        /// ALGORITHM
        /// </summary>
        private static string ALGORITHM = "AES/GCM/NoPadding";
        /// <summary>
        /// TAG_LENGTH_BIT
        /// </summary>
        private static int TAG_LENGTH_BIT = 128;
        /// <summary>
        /// NONCE_LENGTH_BYTE
        /// </summary>
        private static int NONCE_LENGTH_BYTE = 12;

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="associatedData">附加数据包（可能为空）</param>
        /// <param name="nonce">加密使用的随机串初始化向量</param>
        /// <param name="ciphertext">Base64编码后的密文</param>
        /// <returns></returns>
        public static string AesGcmDecrypt(string associatedData, string nonce, string ciphertext)
        {
            GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesEngine());
            AeadParameters aeadParameters = new AeadParameters(
                new KeyParameter(Encoding.UTF8.GetBytes(Config.APIv3_KEY)),
                128,
                Encoding.UTF8.GetBytes(nonce),
                Encoding.UTF8.GetBytes(associatedData));
            gcmBlockCipher.Init(false, aeadParameters);

            byte[] data = Convert.FromBase64String(ciphertext);
            byte[] plaintext = new byte[gcmBlockCipher.GetOutputSize(data.Length)];
            int length = gcmBlockCipher.ProcessBytes(data, 0, data.Length, plaintext, 0);
            gcmBlockCipher.DoFinal(plaintext, length);

            return Encoding.UTF8.GetString(plaintext);
        }
    }
}

